package JAVA并发;

import java.util.concurrent.*;

/**
 * @author zhangmin
 * @create 2022-03-15 20:39
 *
 * 八、J.U.C - 其它组件
 * 1、FutureTask：FutureTask 实现了 RunnableFuture 接口，该接口继承自 Runnable 和 Future<V> 接口，这使得 FutureTask 既可以当做一个任务执行，也可以有返回值。
 *              FutureTask 可用于异步获取执行结果或取消执行任务的场景。当一个计算任务需要执行很长时间，那么就可以用 FutureTask 来封装这个任务，
 *              主线程在完成自己的任务之后再去获取结果。
 * 2、BlockingQueue：java.util.concurrent.BlockingQueue 接口有以下阻塞队列的实现：-----【可以用来实现生产者消费者问题】
 *                  FIFO 队列 ：LinkedBlockingQueue、ArrayBlockingQueue（固定长度）
 *                  优先级队列 ：PriorityBlockingQueue
 *                  提供了阻塞的 take() 和 put() 方法：如果队列为空 take() 将阻塞，直到队列中有内容；如果队列为满 put() 将阻塞，直到队列有空闲位置。
 *3、ForkJoin：主要用于并行计算中，和 MapReduce 原理类似，都是把大的计算任务拆分成多个小任务并行计算。
 *
 */





public class JUC_other8 {
    private static BlockingQueue<String> queue=new ArrayBlockingQueue<>(5);
    private static class Producer extends Thread{
        public void run(){
            try {
                queue.put("product");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Produce...");
        }
    }
    private static class Consumer extends Thread{
        public void run(){
            try {
                queue.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("consum...");
        }
    }


    public static void main(String[] args) throws ExecutionException, InterruptedException {
        /*FutureTask<Integer> futureTask=new FutureTask<>(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                //通过futureTask来异步获取一个长时间任务的结果
                int res=0;
                for (int i = 0; i < 100; i++) {
                    Thread.sleep(10);
                    res+=i;
                }
                return res;
            }
        });
        Thread computeThread=new Thread(futureTask);
        computeThread.start();
        Thread otherThread=new Thread(()->{
            System.out.println("other task is running...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        //启动主线程，计算线程在后台计算，最后再去取结果即可
        otherThread.start();
        System.out.println(futureTask.get());*/


        //生产者，消费者
        for (int i = 0; i < 2; i++) {
            Producer producer=new Producer();
            producer.start();
        }
        //5个消费者，只能获得2个产品，然后阻塞等待剩下3个生产出来
        for (int i = 0; i < 5; i++) {
            Consumer consumer=new Consumer();
            consumer.start();
        }
        //后面的3个生产者是生产一个消费一个，以为消费者已经在等待了
        for (int i = 0; i < 3; i++) {
            Producer producer=new Producer();
            producer.start();
        }
    }
}
